﻿using Model;
using Model.Enum;
using MQTTTool.Controls;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

namespace MQTTTool.Util
{
	public class MQTTUtil
	{
		public delegate void ShowFuZhi(string key);
		public static event ShowFuZhi showfuzhi;
		static MqttClient mqtt;
		public Dictionary<UInt64, string> zidian = new Dictionary<UInt64, string>();
		//public static MQTTUtil mtutil;
		MqttPage page;

		public MQTTUtil(MQConfig mQTTConfig, Controls.MqttPage mqttPage)
		{

			if (!string.IsNullOrWhiteSpace(mQTTConfig.sbbh))
			{
				this.page = mqttPage;
				string topic = "UploadDataResult/" + mQTTConfig.sbbh;
				mqtt = new MqttClient(mQTTConfig.MQTTIP, mQTTConfig.MQTTPort, false, null, null,MqttSslProtocols.TLSv1_2);
				mqtt.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });

				mqtt.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
				mqtt.ConnectionClosed += (sender, e) =>
				{
					if (!mqtt.IsConnected)
					{
						Console.WriteLine(topic + ":mqtt连接失败,重新进行连接>>>");
						mqtt.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });

						Mqtt(topic);
					}

				};
				string clientId = "tk-" + mQTTConfig.sbbh;
				string username = mQTTConfig.username;
				string password = mQTTConfig.password;
				try
				{
					mqtt.Connect(clientId, username, password);
					if (!mqtt.IsConnected)
					{

						// showfuzhi?.Invoke(NetWorkConfig.GetSBBH());
					}

				}
				catch (Exception e)
				{
					//  showfuzhi?.Invoke(NetWorkConfig.GetSBBH());
					//throw;
				}

				

			}

		}
		public static void Deployee()
		{
			mqtt.Disconnect();


		}
		/// <summary>
		/// 改变设备编号
		/// </summary>
		/// <param name="toptic">主题</param>
		/// <param name="mqttMsgBase">接收消息的枚举</param>
		public void ChangeSBBH(string sbbh)
		{
			// mqtt.Disconnect();
			mqtt.Disconnect();
			//new MQTTUtil();

		}

		

	
		/// <summary>
		/// 找不到不会抛出异常
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public string GetMassage(UInt64 key, out bool hasr)
		{
			
			if (!zidian.ContainsKey(key))
			{
				//  zidian.Remove(key);
				hasr = false;
				return "";
			}
			string val = zidian[key];
			hasr = true;
			return val;
		}

		internal void DisConnect()
		{
			mqtt.Disconnect();
		}

		private void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
		{
			if (zidian.Count > 100)
			{
				zidian.Clear();
			}
			
			string msg = Encoding.GetEncoding("GBK").GetString(e.Message);
			
				zidian.Add(num1, msg);
				num1++; ;
				page?.AddLog("收到回复: " + msg, LogEnum.ReceverLog);
		

		}
		UInt64 num1 = 0;
		//  UInt64 num2 = 0;
		/// <summary>
		/// mqtt 消息订阅
		/// </summary>
		/// <param name="tbMonitorMac"></param>
		public UInt64 Mqtt(string msg)
		{
			string topic = "DataUpdate";//
										//+ FanWen.GetIPStr();

			//            string clientId = Guid.NewGuid().ToString();
			//无需用户名和密码
			//mqtt.Connect(clientId);
			//需要使用用户名和密码进行连接
			//消息发布
			//mqtt.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
			mqtt.Publish(topic, Encoding.GetEncoding("GB2312").GetBytes(msg), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
			return num1;
		}
		
		/// <summary>
		/// 订阅该设备编号有关主题
		/// </summary>
		/// <param name="sbbh"></param>
		public static void Subscrbe(string sbbh)
		{

			string topic = "UploadDataResult/" + sbbh;
			mqtt.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
		}

		public string SendMsgAndGetResult(string msg,long timeout) {
			string result = "";
			try
			{
				ulong i = Mqtt(msg);//发送消息
				bool getvalue = false;
				DateTime starttime = DateTime.Now;
				while (!getvalue)
				{
					try
					{

						 result = GetMassage(i,out getvalue);
					}
					catch (Exception)
					{


					}
					if (DateTime.Now.Millisecond - starttime.Millisecond > timeout)
					{
						break;
					}
					Thread.Sleep(20);
				}
				
			}
			catch (Exception ex)
			{
				page.AddLog(ex.Message + ex.StackTrace, LogEnum.ErrLog);
				return "";
			}
			return result;
		}
	}
}
